package com.shycloud.mido.member.service.impl;

import com.shycloud.mido.member.api.vo.TeacherVO;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.joy.zebra.common.push.JPushUtils;
import com.shycloud.mido.common.core.config.JacksonConfig;
import com.shycloud.mido.homework.api.enums.JPushCodeEnum;
import com.shycloud.mido.member.api.entity.*;
import com.shycloud.mido.member.service.MsgMainService;
import com.shycloud.mido.member.service.MsgMemberInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shycloud.mido.common.core.constant.CommonConstants;
import com.shycloud.mido.common.core.exception.BusinessException;
import com.shycloud.mido.common.core.util.R;
import com.shycloud.mido.common.security.util.SecurityUtils;
import com.shycloud.mido.member.api.vo.MyTeacherVO;
import com.shycloud.mido.member.api.vo.SmMemberTeacherGroupVO;
import com.shycloud.mido.member.api.vo.StudentVO;
import com.shycloud.mido.member.config.PropertiesConfig;
import com.shycloud.mido.member.mapper.MemberMapper;
import com.shycloud.mido.member.mapper.OrgRelationshipUnlinkLogMapper;
import com.shycloud.mido.member.mapper.OrgStudentDetailedMapper;
import com.shycloud.mido.member.mapper.OrgTeacherDetailedMapper;
import com.shycloud.mido.member.mapper.OrgTeacherStudentMapper;
import com.shycloud.mido.member.mapper.SmMemberGroupStudentMapper;
import com.shycloud.mido.member.mapper.SmMemberTeacherGroupMapper;
import com.shycloud.mido.member.mapper.TeacherMapper;
import com.shycloud.mido.member.service.TeacherService;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 教师模块实现类
 *
 * @author nianhua.jiang
 * @date 2020/6/16 13:55
 */
@Slf4j
@Service
@AllArgsConstructor
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {

	/** 教师模块 mapper */
	private final TeacherMapper teacherMapper;
	/** 教师详情模块 mapper */
	private final OrgTeacherDetailedMapper teacherDetailedMapper;
	/** 教师分组模块 mapper */
	private final SmMemberTeacherGroupMapper groupMapper;
	/** 学生分组模块 mapper */
	private final SmMemberGroupStudentMapper groupStudentMapper;
	/** 学生模块 mapper */
	private final OrgStudentDetailedMapper studentDetailedMapper;
	/** 教师-学生 关联 mapper */
	private final OrgTeacherStudentMapper teacherStudentMapper;

	/** 用户模块 mapper */
	private final MemberMapper memberMapper;

	/** 老师学生解除绑定记录 mapper */
	private final OrgRelationshipUnlinkLogMapper unlinkLogMapper;

	private PropertiesConfig propertiesConfig;
	/** 发送消息模块 service */
	private MsgMemberInfoService memberInfoService;
	/** 消息模块 service */
	private MsgMainService msgMainService;

	/**
	 * 我的老师
	 *
	 * @param memberId
	 * @return com.shycloud.mido.member.api.vo.MyTeacherVO
	 * @author nianhua.jiang
	 * @date 2020/6/16 13:54
	 */
	@Override
	public MyTeacherVO getMyTeacher(String memberId, Integer orgId) {

		//0为用户没绑定教师
		if (orgId == 0) {
			return new MyTeacherVO();
		}

		//根据memberId获取学生ID
		OrgStudentDetailed studentDetailed = studentDetailedMapper.selectOne(new QueryWrapper<OrgStudentDetailed>()
				.eq(OrgStudentDetailed.COL_MEMBER_ID, memberId)
				.and(x -> x.eq(OrgStudentDetailed.COL_ORG_ID, orgId))
				.and(y -> y.eq(OrgStudentDetailed.COL_DEL_FLAG, "0")));

		if (studentDetailed == null) {
			return new MyTeacherVO();
		}

		OrgTeacherStudent teacherStudent = teacherStudentMapper.selectOne(new QueryWrapper<OrgTeacherStudent>()
				.eq("student_id", studentDetailed.getId()));

		if (teacherStudent == null) {
			return new MyTeacherVO();
		}

		//返回教师信息
		MyTeacherVO myTeacher = teacherMapper.getMyTeacher(teacherStudent.getTeacherId());

		OrgTeacherDetailed orgTeacherDetailed = teacherDetailedMapper.selectById(teacherStudent.getTeacherId());

		if (orgTeacherDetailed != null && CommonConstants.STATUS_NORMAL.equals(orgTeacherDetailed.getDelFlag())) {
			myTeacher.setApproval("1");
		}

		String memberIdTeacher = orgTeacherDetailed.getMemberId();

		Member member = memberMapper.selectById(memberIdTeacher);

		//教师电话号
		myTeacher.setPhone(member.getUsername());
		//ID
		myTeacher.setAccount(member.getAccount());

		myTeacher.setImId(member.getImUserId());
		return myTeacher;

	}

	@Override
	public MyTeacherVO getMyTeacher(String studentId) {

		OrgTeacherStudent teacherStudent = teacherStudentMapper.selectOne(new QueryWrapper<OrgTeacherStudent>()
				.eq("student_id", studentId));

		if (teacherStudent == null) {
			return null;
		}

		//返回教师信息
		MyTeacherVO myTeacher = teacherMapper.getMyTeacher(teacherStudent.getTeacherId());

		OrgTeacherDetailed orgTeacherDetailed = teacherDetailedMapper.selectById(teacherStudent.getTeacherId());

		if (orgTeacherDetailed != null && CommonConstants.STATUS_NORMAL.equals(orgTeacherDetailed.getDelFlag())) {
			myTeacher.setApproval("1");
		}

		String memberIdTeacher = orgTeacherDetailed.getMemberId();

		Member member = memberMapper.selectById(memberIdTeacher);

		//教师电话号
		myTeacher.setPhone(member.getUsername());
		//ID
		myTeacher.setAccount(member.getAccount());

		myTeacher.setImId(member.getImUserId());

		myTeacher.setTeacherId(teacherStudent.getTeacherId());

		myTeacher.setHeader(member.getAvatar());

		myTeacher.setMemberShowName(member.getShowname());

		return myTeacher;
	}

	/**
	 * 获取学生列表
	 *
	 * @param page     分页参数
	 * @param orgId    机构ID
	 * @param groupId  分组ID
	 * @param memberId 用户ID
	 * @return com.shycloud.mido.member.api.vo.StudentVO
	 * @author nianhua.jiang
	 * @date 2020/6/19 18:29
	 */
	@Override
	public IPage<StudentVO> getStudentDetail(Page page, Integer orgId, Integer groupId, String memberId) {

		//根据 member_id 和 org_id 获取教师 id
		OrgTeacherDetailed orgTeacherDetailed = getTeacher(orgId, memberId);
		IPage<StudentVO> studentDetail = teacherMapper.getStudentDetail(page, groupId, orgTeacherDetailed.getId());
		return studentDetail;
	}

	/**
	 * 教师获取学生分组列表
	 *
	 * @param orgId
	 * @return java.util.Map<java.lang.String, java.lang.Object>
	 * @author nianhua.jiang
	 * @date 2020/6/22 11:18
	 */
	@Override
	public List<SmMemberTeacherGroupVO> getGroupList(Integer orgId) {

		//根据教师所在机构和memberId获取教师ID
		OrgTeacherDetailed orgTeacherDetailed = getTeacher(orgId, SecurityUtils.getMember().getId());
		String teacherId = orgTeacherDetailed.getId();

		//返回查询结果
		List<SmMemberTeacherGroupVO> groupList = groupMapper.getGroupList(teacherId);

		return groupList;

	}

	/**
	 * 获取学生个数
	 *
	 * @param orgId
	 * @param memberId
	 * @return int
	 * @author nianhua.jiang
	 * @date 2020/6/23 17:55
	 */
	@Override
	public int getStudentCount(Integer orgId, String memberId) {

		//根据教师所在机构和memberId获取教师ID
		OrgTeacherDetailed orgTeacherDetailed = getTeacher(orgId, SecurityUtils.getMember().getId());
		String teacherId = orgTeacherDetailed.getId();

		//返回查询结果
		return teacherMapper.getStudentCount(teacherId);
	}

	/**
	 * 获取教师ID
	 *
	 * @param
	 * @return com.shycloud.mido.member.api.entity.OrgTeacherDetailed
	 * @author nianhua.jiang
	 * @date 2020/6/22 16:43
	 */
	@Override
	public OrgTeacherDetailed getTeacher(Integer orgId, String memberId) {
		return teacherDetailedMapper.selectOne(new QueryWrapper<OrgTeacherDetailed>()
				.eq(OrgTeacherDetailed.COL_ORG_ID, orgId)
				.and(x -> x.eq(OrgTeacherDetailed.COL_MEMBER_ID, memberId)));
	}

	@Override
	public String getCurTeacherIdByStudentId(String studentId) {
		//获取最新TeacherId(有可能有多条记录，获取最新的一条表示当前学生的老师的绑定关系)
		List<OrgTeacherStudent> list = teacherStudentMapper.selectList(new QueryWrapper<OrgTeacherStudent>()
				.eq(OrgTeacherStudent.COL_STUDENT_ID, studentId)
				.orderByDesc(OrgTeacherStudent.COL_ID));
		return list.size() == 0 ? null : list.get(0).getTeacherId();
	}

	@Override
	public List<String> getTeacherIdsByStudentId(String studentId) {
		return teacherStudentMapper.getTeacherIdsByStudentId(studentId);
	}

	/**
	 * 教师添加学生
	 *
	 * @param orgId
	 * @param teacherId
	 * @param studentMemberId
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/7/1 10:25
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public Boolean addStudentByTeacher(Integer orgId, String teacherId, String studentMemberId, OrgStudentDetailed studentDetailed) {

		//更新学生表，将其归属到教师对应的机构下
		studentDetailed.setOrgId(orgId);

		studentDetailedMapper.updateById(studentDetailed);

		OrgTeacherStudent orgTeacherStudent = new OrgTeacherStudent();
		//机构ID
		orgTeacherStudent.setOrgId(orgId);
		//学生ID
		orgTeacherStudent.setStudentId(studentDetailed.getId());
		//绑定虚拟账号
		orgTeacherStudent.setTeacherId(teacherId);
		//增加师生关系创建时间
		orgTeacherStudent.setCreateTime(LocalDateTime.now());

		//新增教师-学生关系
		teacherStudentMapper.insert(orgTeacherStudent);

		return true;
	}

	/**
	 * 批量移除学生
	 *
	 * @param studentIdArr
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/8/3 10:51
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public Boolean removeStudentBatch(List<String> studentIdArr, Integer orgId) {

		//获取教师ID
		OrgTeacherDetailed teacher = getTeacher(orgId, SecurityUtils.getMember().getId());

		if (teacher == null) {
			throw new BusinessException(new R(CommonConstants.FAIL, "教师信息获取失败", false));
		}

		for (String studentId : studentIdArr) {

			//移除师生关系
			teacherStudentMapper.delete(new QueryWrapper<OrgTeacherStudent>()
					.eq(OrgTeacherStudent.COL_TEACHER_ID, teacher.getId())
					.and(x -> x.eq(OrgTeacherStudent.COL_STUDENT_ID, studentId)));

			//将学生移除值教师分组外
			groupStudentMapper.delete(new QueryWrapper<SmMemberGroupStudent>().eq(SmMemberGroupStudent.COL_STUDENT_ID, studentId));

			//更新学生机构为 - 0 暂无机构
			OrgStudentDetailed orgStudentDetailed = studentDetailedMapper.selectById(studentId);
			orgStudentDetailed.setOrgId(0);
			studentDetailedMapper.updateById(orgStudentDetailed);

			//清空学生在线课可用时长 - 将 member 表的机构ID也置为 0
			Member member = memberMapper.selectById(orgStudentDetailed.getMemberId());
			//此处增加容错
			if (member != null) {
				member.setOnlineCourseValidTime(0);
				member.setOrgId(0);
				memberMapper.updateById(member);
			}
			//加入到解绑记录表里
			OrgRelationshipUnlinkLog log = new OrgRelationshipUnlinkLog();
			log.setStudentId(studentId);
			log.setTeacherId(teacher.getId());
			log.setCreateTime(LocalDateTime.now());
			unlinkLogMapper.insert(log);

			try {
				//发送消息
				// -------------------------- 给学生发送解绑信息 ------------------------------//
				JPushUtils.sendJPush("老师离开", "您有老师解除了和您的关系", member.getClientId());
				JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(), member.getClientId(), "请求 getMsgApp 接口");
				//编辑消息
				//String msgIdS = addMsg("老师离开", "您有老师解除了和您的关系", memberS.getClientId(), "", "", "2");
				String msgIdS = "teacher_remove_to_student";
				//发送消息
				memberInfoService.sendMsg(msgIdS, "sys", member.getId());
				//------------------------------------------------------------------------//
			} catch (Exception e) {
				continue;
			}


		}

		return true;
	}

	/**
	 * 添加学生
	 *
	 * @param orgId
	 * @param memberId
	 * @return com.shycloud.mido.member.api.entity.OrgStudentDetailed
	 * @author nianhua.jiang
	 * @date 2020/7/1 10:53
	 */
	private OrgStudentDetailed addStudent(Integer orgId, String memberId) {

		//添加学生
		OrgStudentDetailed student = new OrgStudentDetailed();
		//memberId
		student.setMemberId(memberId);
		//机构ID
		student.setOrgId(orgId);
		//创建时间
		student.setCreateTime(new Date());
		//逻辑删除
		student.setDelFlag(CommonConstants.STATUS_NORMAL);
		//昵称
		student.setName(memberMapper.selectById(memberId).getShowname());
		studentDetailedMapper.insert(student);
		return student;
	}


	/**
	 * 家长获取学生列表（这个号本身）
	 *
	 * @param orgId
	 * @param memberId
	 * @return com.baomidou.mybatisplus.core.metadata.IPage<com.shycloud.mido.member.api.vo.StudentVO>
	 * @author nianhua.jiang
	 * @date 2020/9/5 9:11
	 **/
	@Override
	public IPage<StudentVO> getStudentByParent(Integer orgId, String memberId) {
		return teacherMapper.getStudentByParent(new Page(1, 10), orgId, memberId);
	}


	/**
	 * 获取学生详情
	 *
	 * @param studentId
	 * @return com.shycloud.mido.member.api.vo.StudentVO
	 * @author nianhua.jiang
	 * @date 2020/11/5 10:46
	 **/
	@Override
	public StudentVO getStudentInfo(String studentId) {

		StudentVO studentInfo = teacherMapper.getStudentInfo(studentId);

		String phone = studentInfo.getPhone();

		if (!StringUtils.isEmpty(phone)) {
			StringBuilder stringBuilder = new StringBuilder(phone);
			studentInfo.setPhone(stringBuilder.replace(3, 7, "****").toString());
		}

		return studentInfo;
	}

	/**
	 * 搜索学生
	 *
	 * @param name
	 * @return com.baomidou.mybatisplus.core.metadata.IPage<com.shycloud.mido.member.api.vo.StudentVO>
	 * @author nianhua.jiang
	 * @date 2020/11/5 14:54
	 **/
	@Override
	public IPage<StudentVO> searchStudent(Integer current, Integer size, String name, String teacherId) {
		return teacherMapper.searchStudent(new Page(current, size), name, teacherId);
	}

	/**
	 * 解除师生关系
	 *
	 * @param studentId
	 * @param teacherId
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/11/5 17:46
	 **/
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public Boolean dismiss(String studentId, String teacherId, String identity) {

		//1.移除学生，将学生详情表orgId字段改为 0 - 无归属机构
		OrgStudentDetailed orgStudentDetailed = studentDetailedMapper.selectById(studentId);
		orgStudentDetailed.setOrgId(0);
		studentDetailedMapper.updateById(orgStudentDetailed);
		//2.删除教师与学生的绑定关系
		teacherStudentMapper.delete(new QueryWrapper<OrgTeacherStudent>()
				.eq(OrgTeacherStudent.COL_STUDENT_ID, studentId)
				.eq(OrgTeacherStudent.COL_TEACHER_ID, teacherId));
		//3.移除教师与学生的关联分组表
		teacherMapper.removeTeacherGroup(studentId);

		//4.member的 org_id 字段更新成 0 无归属机构
		Member memberS = memberMapper.selectById(orgStudentDetailed.getMemberId());
		memberS.setOrgId(0);
		memberMapper.updateById(memberS);

		//5.加入到解绑记录表里
		OrgRelationshipUnlinkLog log = new OrgRelationshipUnlinkLog();
		log.setStudentId(studentId);
		log.setTeacherId(teacherId);
		log.setCreateTime(LocalDateTime.now());
		unlinkLogMapper.insert(log);

		//获取教师信息
		OrgTeacherDetailed orgTeacherDetailed = teacherDetailedMapper.selectById(teacherId);
		Member memberT = memberMapper.selectById(orgTeacherDetailed.getMemberId());

		//6.执行推送程序 2021-06-10
		if ("0".equals(identity)) {
			//-------------------------- 给教师发送解绑信息 ------------------------------//
			JPushUtils.sendJPush("学生离开", "您有学生解除了和您的关系", memberT.getClientId());
			JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(), memberT.getClientId(), "请求 getMsgApp 接口");
			//编辑消息
			//String msgId = addMsg("学生离开", "您有学生解除了和您的关系", memberT.getClientId(), "", "", "1");
			String msgId = "student_remove_to_teacher";
			//发送消息
			memberInfoService.sendMsg(msgId, "sys", memberT.getId());
			//------------------------------------------------------------------------//

		}
		if ("1".equals(identity)) {
			//-------------------------- 给学生发送解绑信息 ------------------------------//
			JPushUtils.sendJPush("老师离开", "您有老师解除了和您的关系", memberS.getClientId());
			JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(), memberS.getClientId(), "请求 getMsgApp 接口");
			//编辑消息
			//String msgIdS = addMsg("老师离开", "您有老师解除了和您的关系", memberS.getClientId(), "", "", "2");
			String msgIdS = "teacher_remove_to_student";
			//发送消息
			memberInfoService.sendMsg(msgIdS, "sys", memberS.getId());
			//------------------------------------------------------------------------//
		}

		return true;
	}

	@Override
	public List<StudentVO> getStudentList(String teacherId) {
		return teacherMapper.getStudentList(teacherId);
	}

	@Override
	public StudentVO getStudent(String studentId) {
		return teacherMapper.getStudent(studentId);
	}

	@Override
	public Map getStudentAssignBal(String studentId) {
		Map returnMap = null;

		try {
			OrgStudentDetailed studentDetailed = studentDetailedMapper.selectOne(
					new QueryWrapper<OrgStudentDetailed>().eq("id", studentId));

			if (studentDetailed == null) {
				return null;
			}

			returnMap = new HashMap(2);
			returnMap.put("curAssignBal", studentDetailed.getCurAssginBal());
			returnMap.put("nextAssignBal", studentDetailed.getNextAssginBal());

			return returnMap;
		} catch (BusinessException e) {
			log.error(e.getMessage(), e);
			throw e;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new BusinessException(e.getMessage());
		}
	}

	@Override
	public Boolean consumeAssginBal(String studentId, Integer curConsume, Integer nextConsume) {
		OrgStudentDetailed studentDetailed = studentDetailedMapper.selectOne(
				new QueryWrapper<OrgStudentDetailed>().eq("id", studentId));

		if (studentDetailed == null) {
			return null;
		}

		studentDetailed.setCurAssginBal(studentDetailed.getCurAssginBal() != null ?
				studentDetailed.getCurAssginBal() - curConsume : propertiesConfig.getPeriodAssignThreshold() - curConsume);
		studentDetailed.setCurAssginBal(studentDetailed.getNextAssginBal() != null ?
				studentDetailed.getCurAssginBal() - nextConsume : propertiesConfig.getPeriodAssignThreshold() - nextConsume);

		return studentDetailedMapper.updateById(studentDetailed) == 1 ? true : false;
	}

	private String addMsg(String title, String message, String regId, String pushRespCode, String pushRespMsg, String triggerTo) {

		MsgMain msgMain = new MsgMain();
		//给教师发送
		msgMain.setTriggerTo(triggerTo);
		//来自师生绑定/解绑 - 系统自动推送
		msgMain.setTriggerFrom("0");
		//消息下发的场合：师生关系
		msgMain.setPoint("5");
		//不可修改
		msgMain.setModify("0");
		//自动推送
		msgMain.setMode("1");
		//个人
		msgMain.setRangeType("1");
		//有效数据
		msgMain.setDelFlag("0");
		//创建时间
		msgMain.setCreateTime(LocalDateTime.now());
		//消息类型：文本
		msgMain.setMsgType("0");
		//发送时间
		msgMain.setActualPubDatetime(LocalDateTime.now());
		//创建人-> 系统
		msgMain.setCreateUser("sys");
		//消息内容
		msgMain.setMessage(message);
		//发布时间
		msgMain.setPubDatetime(LocalDateTime.now());
		//极光推送唯一ID
		msgMain.setPushId(regId);
		//极光推送返回 code
		msgMain.setPushRespCode(pushRespCode);
		//极光推送返回 msg
		msgMain.setPushRespMsg(pushRespMsg);
		//TODO 推送成功
		msgMain.setPushStatus("0");
		//推送时间
		msgMain.setPushTime(LocalDateTime.now());
		//标题
		msgMain.setTitle(title);
		//家校消息
		msgMain.setType("1");

		return msgMainService.addSysMsg(msgMain);
	}

	@Override
	public OrgTeacherDetailed getTeacherByUsername(String teaUsername) {
		return teacherMapper.getTeacherByUsername(teaUsername);
	}

	@Override
	public OrgTeacherDetailed getTeacherByMemberId(String memberId) {
		return teacherMapper.getTeacherByMemberId(memberId);
	}

	@Override
	public TeacherVO getTeacherInfo(String teacherId) {
		return teacherMapper.getTeacherInfo(teacherId);
	}
}
